package com.xx.springsecuritydemo.main.config;

import com.xx.springsecuritydemo.main.filter.KaptchaFilter;
import com.xx.springsecuritydemo.main.handler.MyAuthenticationFailureHandler;
import com.xx.springsecuritydemo.main.handler.MyAuthenticationSuccessHandler;
import com.xx.springsecuritydemo.main.handler.MyLogoutSuccessHandler;
import com.xx.springsecuritydemo.main.security.MyExpiredSessionStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy;
import org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.util.ArrayList;
import java.util.List;

/**
 * 前后端不分离springSecurity配置类
 */
//@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

//    private final UserDetailsService userDetailsService;
//
//    @Autowired
//    public WebSecurityConfigurer(UserDetailsService
//                                         userDetailsService) {
//        this.userDetailsService = userDetailsService;
//    }
//
//    // 默认使用BCrypt加密算法
//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        return new BCryptPasswordEncoder();
//    }
//
//    /**
//     * 自定义AuthenticationManager
//     *
//     * @param auth
//     * @throws Exception
//     */
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        System.out.println("⾃定义AuthenticationManager: " + auth);
//        // 使用自定义的userDetailsService
//        auth.userDetailsService(userDetailsService);
//    }
//
//    //"作⽤: ⽤来将⾃定义AuthenticationManager在⼯⼚中进⾏暴露,可以在任何位置注⼊
//    @Override
//    @Bean
//    public AuthenticationManager authenticationManagerBean() throws Exception {
//        return super.authenticationManagerBean();
//    }
//
//    /**
//     * 自定义了一个组合模式的会话处理类
//     *
//     * @return
//     */
//    public SessionAuthenticationStrategy sessionAuthenticationStrategy() {
//        List<SessionAuthenticationStrategy> delegateStrategies = new ArrayList<>();
//        delegateStrategies.add(new ChangeSessionIdAuthenticationStrategy());
//        ConcurrentSessionControlAuthenticationStrategy strategy =
//                new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
//        //设置并发会话最大数
//        strategy.setMaximumSessions(1);
//        //设置当超过并发会话最大数时，禁止后来者登录-true
//        strategy.setExceptionIfMaximumExceeded(false);
//        delegateStrategies.add(strategy);
//        delegateStrategies.add(new RegisterSessionAuthenticationStrategy(sessionRegistry()));
//        return new CompositeSessionAuthenticationStrategy(delegateStrategies);
//    }
//
//    /**
//     * 这个类在SpringSecurity中被定义用于保存会话信息，上面创建自定义会话处理类时，需要传到构造器中
//     *
//     * @return
//     */
//    @Bean
//    public SessionRegistry sessionRegistry() {
//        return new SessionRegistryImpl();
//    }
//
//
//    /**
//     * 前后端不分离
//     * 用自定义LoginKaptchaFilter替换UsernamePasswordAuthenticationFilter
//     *
//     * @return
//     * @throws Exception
//     */
//    @Bean
//    public KaptchaFilter kaptchaFilter() throws Exception {
//        KaptchaFilter kaptchaFilter = new KaptchaFilter();
//        kaptchaFilter.setKaptcha("kaptcha");
//        // 3.指定认证管理器
//        kaptchaFilter.setAuthenticationManager(authenticationManagerBean());
//        // 4.指定成功时处理
//        kaptchaFilter.setAuthenticationSuccessHandler(new MyAuthenticationSuccessHandler());
//        // 5.认证失败处理
//        kaptchaFilter.setAuthenticationFailureHandler(new MyAuthenticationFailureHandler());
//        kaptchaFilter.setFilterProcessesUrl("/doLogin");
//        kaptchaFilter.setUsernameParameter("username");
//        kaptchaFilter.setPasswordParameter("password");
//        // 指定会话管理策略，不指定会导致会话管理失效
//        kaptchaFilter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy());
//        return kaptchaFilter;
//    }
//
//    /**
//     * session事件发布者
//     *
//     * @return
//     */
//    @Bean
//    public HttpSessionEventPublisher httpSessionEventPublisher() {
//        return new HttpSessionEventPublisher();
//    }
//
//
//    /**
//     * 自定义请求处理
//     *
//     * @param http
//     * @throws Exception
//     */
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.authorizeHttpRequests()
//                .mvcMatchers("/login.html").permitAll()
//                .mvcMatchers("/index").permitAll()
//                .mvcMatchers("/vc.jpg").permitAll()
//                .anyRequest().authenticated()
//                .and()
//                .formLogin()
//                .loginPage("/login.html") // 登录页
//                .loginProcessingUrl("/doLogin") // 登录接口
//                .usernameParameter("username") // username名字
//                .passwordParameter("password") // password名字
//                .successHandler(new MyAuthenticationSuccessHandler())
//                .failureHandler(new MyAuthenticationFailureHandler())
//                .and()
//                .logout()
//                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
//                .invalidateHttpSession(true)
//                .clearAuthentication(true)
//                .logoutSuccessHandler(new MyLogoutSuccessHandler())
//                .and()
//                .rememberMe()
//                .key("uniqueAndSecret") // 设置一个唯一密钥
//                .tokenValiditySeconds(86400) // 设置记住我的有效期为 1 天
//                .and()
//                .csrf().disable();
//        http.addFilterAt(kaptchaFilter(), UsernamePasswordAuthenticationFilter.class);
//
//        http.sessionManagement()
//                .maximumSessions(1)
//                .expiredUrl("/login.html");
//    }
}
